﻿using System.Diagnostics;
using System.Windows;
using K9Nano.Updater.Client.Logging;
using K9Nano.Updater.Client.ViewModels;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Serilog;

namespace K9Nano.Updater.Client;

/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
    public App()
    {
        var appMutex = new Mutex(true, "K9NanoUpdaterClient", out var createdNew);
        if (!createdNew)
        {
            this.Shutdown();
            return;
        }

        this.Startup += OnAppStartup;
        this.Exit += OnAppExitting;
        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

        try
        {
            if (System.IO.File.Exists(Constants.LogFile))
            {
                System.IO.File.Delete(Constants.LogFile);
            }
        }
        catch
        {
            // ignore
        }

        Log.Logger = new LoggerConfiguration()
        .WriteTo.File(Constants.LogFile,
            outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}")
        .CreateLogger();
    }

    private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        Log.Logger.Fatal(e.ExceptionObject as Exception, "意外错误");
    }


    private void OnAppExitting(object sender, ExitEventArgs e)
    {
        try
        {
            Log.CloseAndFlush();
        }
        catch
        {
            // ignore
        }
    }

    private void ConfigureServices(IServiceCollection services, string[] args)
    {
        services.AddLogging(opt =>
        {
            opt.AddProvider(new DelegateLoggerProvider());
            opt.AddSerilog(dispose: true);
        });

        var configuration = new ConfigurationBuilder()
            .AddCommandLine(args)
            .Build();

        services.AddK9Update(opt =>
        {
            configuration.GetSection(Constants.ConfigurationSectionName).Bind(opt);
            opt.Valiate();
        });

        services.AddSingleton<MainWindow>()
            .AddSingleton<MainWindowViewModel>()
            ;
    }

    private async void OnAppStartup(object sender, StartupEventArgs e)
    {
        Log.Logger.Information("更新程序启动");
        try
        {
            IocHelper.ConfigureServices(services =>
            {
                this.ConfigureServices(services, e.Args);
            });

            var manager = IocHelper.GetService<IUpdateManager>();

            var latestVersion = await manager.GetAvailableVersionAsync();
            if (latestVersion is null)
            {
                Log.Logger.Information("无更新版本，程序退出");
                this.Shutdown();
                return;
            }

            var window = IocHelper.GetService<MainWindow>();
            if(window.DataContext is MainWindowViewModel vm)
            {
                vm.LatestVersion = latestVersion;
            }
            window.Show();
        }
        catch (Exception ex)
        {
            Log.Logger.Fatal(ex, "启动失败");

            this.Shutdown();
        }
    }
}
